<?php
namespace plugin\ky_black\app\admin\controller;

use support\Request;
use support\Response;
use support\Db;
use plugin\ky_black\app\admin\model\BlackCard;
use plugin\ky_black\app\admin\model\CardRecharge;
use plugin\ky_black\app\admin\model\CardQuotaAllocation;
use plugin\ky_black\app\admin\model\CardBalanceLog;
use plugin\ky_black\app\admin\validate\BlackCardValidate;

class BlackCardController extends BaseController
{
    /**
     * 黑卡列表
     */
    public function list(Request $request): Response
    {
        $page = (int)$request->input('page', 1);
        $pageSize = (int)$request->input('pageSize', 15);
        $keyword = $request->input('keyword', '');
        $type = $request->input('type', '');
        $status = $request->input('status', '');
        $orgName = $request->input('org_name', '');
        $userName = $request->input('user_name', '');

        // 使用 join 查询以提高性能
        $query = BlackCard::select('ky_black_card.*', 'u.name as user_name', 'o.company_name as org_name')
            ->leftJoin('ky_user as u', 'ky_black_card.user_id', '=', 'u.user_id')
            ->leftJoin('ky_organization as o', 'ky_black_card.org_id', '=', 'o.org_id');

        // 卡号搜索
        if ($keyword) {
            $query->where('ky_black_card.card_no', 'like', "%{$keyword}%");
        }

        // 企业名称搜索
        if ($orgName) {
            $query->where('o.company_name', 'like', "%{$orgName}%");
        }

        // 用户姓名搜索
        if ($userName) {
            $query->where('u.name', 'like', "%{$userName}%");
        }

        // 卡片类型
        if ($type) {
            $query->where('ky_black_card.card_type', $type);
        }

        // 状态
        if ($status !== '') {
            $query->where('ky_black_card.status', (int)$status);
        }

        $total = $query->count();
        $list = $query->orderBy('ky_black_card.card_id', 'desc')
            ->offset(($page - 1) * $pageSize)
            ->limit($pageSize)
            ->get();

        return $this->success([
            'list' => $list,
            'total' => $total
        ]);
    }

    /**
     * 黑卡充值
     */
    public function recharge(Request $request): Response
    {
        $data = $request->post();
        
        // 数据验证
        if (empty($data['card_no'])) {
            return $this->error('请输入卡号');
        }
        if (empty($data['amount']) || $data['amount'] <= 0) {
            return $this->error('请输入正确的充值金额');
        }
        if (empty($data['payment_type'])) {
            return $this->error('请选择支付方式');
        }

        // 查找黑卡
        if (!$card = BlackCard::where('card_no', $data['card_no'])->first()) {
            return $this->error('卡号不存在');
        }

        // 生成充值单号
        $data['recharge_no'] = 'R' . date('YmdHis') . rand(1000, 9999);
        $data['card_id'] = $card->card_id;
        $data['status'] = 'pending';
        $data['verify_status'] = false;

        try {
            Db::connection()->transaction(function() use ($data, $card) {
                // 创建充值记录
                $recharge = CardRecharge::create($data);

                // 记录余额变更日志
                CardBalanceLog::create([
                    'card_id' => $card->card_id,
                    'card_no' => $card->card_no,
                    'change_type' => 'recharge',
                    'amount' => $data['amount'],
                    'before_balance' => $card->balance,
                    'after_balance' => bcadd($card->balance, $data['amount'], 2),
                    'before_available' => $card->available_balance,
                    'after_available' => bcadd($card->available_balance, $data['amount'], 2),
                    'before_frozen' => $card->frozen_balance,
                    'after_frozen' => $card->frozen_balance,
                    'related_id' => $data['recharge_no'],
                    'operator_id' => $data['operator_id'] ?? null,
                    'operator_name' => $data['operator_name'] ?? null,
                    'remark' => $data['remark'] ?? null
                ]);

                // 更新卡片余额
                $card->update([
                    'balance' => bcadd($card->balance, $data['amount'], 2),
                    'available_balance' => bcadd($card->available_balance, $data['amount'], 2)
                ]);
            });

            return $this->success([], '充值成功');
        } catch (\Exception $e) {
            return $this->error('充值失败：' . $e->getMessage());
        }
    }

    /**
     * 额度分配
     */
    public function allocateQuota(Request $request): Response
    {
        $data = $request->post();
        
        // 数据验证
        if (empty($data['primary_card_no'])) {
            return $this->error('请输入主卡卡号');
        }
        if (empty($data['sub_card_no'])) {
            return $this->error('请输入子卡卡号');
        }
        if (empty($data['amount']) || $data['amount'] <= 0) {
            return $this->error('请输入正确的分配金额');
        }
        if (empty($data['quota_type']) || !in_array($data['quota_type'], ['fixed', 'shared'])) {
            return $this->error('请选择正确的额度类型');
        }

        // 查找主卡
        if (!$primaryCard = BlackCard::where('card_no', $data['primary_card_no'])->first()) {
            return $this->error('主卡号不存在');
        }

        // 查找子卡
        if (!$subCard = BlackCard::where('card_no', $data['sub_card_no'])->first()) {
            return $this->error('子卡号不存在');
        }

        // 验证可用余额
        if ($primaryCard->available_balance < $data['amount']) {
            return $this->error('主卡可用余额不足');
        }

        // 生成分配单号
        $data['allocation_no'] = 'A' . date('YmdHis') . rand(1000, 9999);
        $data['primary_card_id'] = $primaryCard->card_id;
        $data['sub_card_id'] = $subCard->card_id;
        $data['operation_type'] = 'allocate';
        $data['before_amount'] = $subCard->available_balance;
        $data['after_amount'] = bcadd($subCard->available_balance, $data['amount'], 2);
        $data['status'] = 'pending';

        try {
            Db::connection()->transaction(function() use ($data, $primaryCard, $subCard) {
                // 创建额度分配记录
                CardQuotaAllocation::create($data);

                // 记录主卡余额变更日志
                CardBalanceLog::create([
                    'card_id' => $primaryCard->card_id,
                    'card_no' => $primaryCard->card_no,
                    'change_type' => 'allocate',
                    'amount' => -$data['amount'],
                    'before_balance' => $primaryCard->balance,
                    'after_balance' => $primaryCard->balance,
                    'before_available' => $primaryCard->available_balance,
                    'after_available' => bcsub($primaryCard->available_balance, $data['amount'], 2),
                    'before_frozen' => $primaryCard->frozen_balance,
                    'after_frozen' => bcadd($primaryCard->frozen_balance, $data['amount'], 2),
                    'related_id' => $data['allocation_no'],
                    'operator_id' => $data['operator_id'] ?? null,
                    'operator_name' => $data['operator_name'] ?? null,
                    'remark' => $data['remark'] ?? null
                ]);

                // 记录子卡余额变更日志
                CardBalanceLog::create([
                    'card_id' => $subCard->card_id,
                    'card_no' => $subCard->card_no,
                    'change_type' => 'allocate',
                    'amount' => $data['amount'],
                    'before_balance' => $subCard->balance,
                    'after_balance' => $subCard->balance,
                    'before_available' => $subCard->available_balance,
                    'after_available' => bcadd($subCard->available_balance, $data['amount'], 2),
                    'before_frozen' => $subCard->frozen_balance,
                    'after_frozen' => $subCard->frozen_balance,
                    'related_id' => $data['allocation_no'],
                    'operator_id' => $data['operator_id'] ?? null,
                    'operator_name' => $data['operator_name'] ?? null,
                    'remark' => $data['remark'] ?? null
                ]);

                // 更新主卡余额
                $primaryCard->update([
                    'available_balance' => bcsub($primaryCard->available_balance, $data['amount'], 2),
                    'frozen_balance' => bcadd($primaryCard->frozen_balance, $data['amount'], 2)
                ]);

                // 更新子卡余额
                $subCard->update([
                    'available_balance' => bcadd($subCard->available_balance, $data['amount'], 2)
                ]);
            });

            return $this->success([], '额度分配成功');
        } catch (\Exception $e) {
            return $this->error('额度分配失败：' . $e->getMessage());
        }
    }

    /**
     * 充值记录列表
     */
    public function rechargeList(Request $request): Response
    {
        $page = (int)$request->input('page', 1);
        $pageSize = (int)$request->input('pageSize', 15);
        $cardNo = $request->input('card_no', '');
        $status = $request->input('status', '');
        $startTime = $request->input('start_time', '');
        $endTime = $request->input('end_time', '');

        $query = CardRecharge::with(['blackCard', 'blackCard.user']);

        if ($cardNo) {
            $query->where('card_no', $cardNo);
        }

        if ($status) {
            $query->where('status', $status);
        }

        if ($startTime) {
            $query->where('created_at', '>=', $startTime);
        }

        if ($endTime) {
            $query->where('created_at', '<=', $endTime);
        }

        $total = $query->count();
        $list = $query->orderBy('recharge_id', 'desc')
            ->offset(($page - 1) * $pageSize)
            ->limit($pageSize)
            ->get();

        return json([
            'code' => 0,
            'msg' => 'success',
            'data' => [
                'list' => $list,
                'total' => $total
            ]
        ]);
    }

    /**
     * 额度分配记录列表
     */
    public function quotaAllocationList(Request $request): Response
    {
        $page = (int)$request->input('page', 1);
        $pageSize = (int)$request->input('pageSize', 15);
        $primaryCardNo = $request->input('primary_card_no', '');
        $subCardNo = $request->input('sub_card_no', '');
        $status = $request->input('status', '');
        $startTime = $request->input('start_time', '');
        $endTime = $request->input('end_time', '');

        $query = CardQuotaAllocation::with(['primaryCard', 'subCard', 'operator']);

        if ($primaryCardNo) {
            $query->where('primary_card_no', $primaryCardNo);
        }

        if ($subCardNo) {
            $query->where('sub_card_no', $subCardNo);
        }

        if ($status) {
            $query->where('status', $status);
        }

        if ($startTime) {
            $query->where('created_at', '>=', $startTime);
        }

        if ($endTime) {
            $query->where('created_at', '<=', $endTime);
        }

        $total = $query->count();
        $list = $query->orderBy('allocation_id', 'desc')
            ->offset(($page - 1) * $pageSize)
            ->limit($pageSize)
            ->get();

        return json([
            'code' => 0,
            'msg' => 'success',
            'data' => [
                'list' => $list,
                'total' => $total
            ]
        ]);
    }

    /**
     * 余额变更记录列表
     */
    public function balanceLogList(Request $request): Response
    {
        $page = (int)$request->input('page', 1);
        $pageSize = (int)$request->input('pageSize', 15);
        $cardNo = $request->input('card_no', '');
        $changeType = $request->input('change_type', '');
        $startTime = $request->input('start_time', '');
        $endTime = $request->input('end_time', '');

        $query = CardBalanceLog::with(['blackCard', 'operator']);

        if ($cardNo) {
            $query->where('card_no', $cardNo);
        }

        if ($changeType) {
            $query->where('change_type', $changeType);
        }

        if ($startTime) {
            $query->where('created_at', '>=', $startTime);
        }

        if ($endTime) {
            $query->where('created_at', '<=', $endTime);
        }

        $total = $query->count();
        $list = $query->orderBy('log_id', 'desc')
            ->offset(($page - 1) * $pageSize)
            ->limit($pageSize)
            ->get();

        return json([
            'code' => 0,
            'msg' => 'success',
            'data' => [
                'list' => $list,
                'total' => $total
            ]
        ]);
    }

    /**
     * 创建黑卡
     */
    public function create(Request $request): Response
    {
        $data = $request->post();
        
        // 如果提交的是 organization_id，转换为 org_id
        if (isset($data['organization_id'])) {
            $data['org_id'] = $data['organization_id'];
            unset($data['organization_id']);
        }
        
        // 生成卡号（如果没有提供）
        if (empty($data['card_no'])) {
            $data['card_no'] = $this->generateCardNo();
        }
        
        // 添加调试信息
        error_log("Creating card with data: " . json_encode($data));
        
        // 设置默认值
        $data['status'] = $data['status'] ?? 0; // 默认未使用
        $data['balance'] = $data['balance'] ?? 0;
        $data['available_balance'] = $data['available_balance'] ?? 0;
        $data['frozen_balance'] = $data['frozen_balance'] ?? 0;
        $data['total_consumption'] = $data['total_consumption'] ?? 0;
        $data['generate_time'] = date('Y-m-d H:i:s');
        
        // 如果没有提供生效时间，默认为当前时间
        if (empty($data['effect_time'])) {
            $data['effect_time'] = date('Y-m-d H:i:s');
        }
        
        // 检查卡号是否存在
        $existingCard = BlackCard::where('card_no', $data['card_no'])->first();
        if ($existingCard) {
            error_log("Card number already exists in database: " . $data['card_no']);
            return $this->error('卡号已存在');
        }
        
        // 验证数据
        $validate = new BlackCardValidate();
        if (!$validate->scene('create')->check($data)) {
            error_log("Validation failed: " . $validate->getError());
            return $this->error($validate->getError());
        }

        try {
            // 如果是机构卡，检查机构是否存在
            if ($data['card_type'] === 'organization' && !empty($data['org_id'])) {
                $org = \plugin\ky_black\app\admin\model\Organization::find($data['org_id']);
                if (!$org) {
                    return $this->error('机构不存在');
                }
            }
            // 如果是个人卡，检查用户是否存在
            else if ($data['card_type'] === 'personal' && !empty($data['user_id'])) {
                $user = \plugin\ky_black\app\admin\model\User::find($data['user_id']);
                if (!$user) {
                    return $this->error('用户不存在');
                }
            }

            // 创建黑卡
            $card = BlackCard::create($data);
            
            // 记录操作日志
            CardBalanceLog::create([
                'card_id' => $card->card_id,
                'card_no' => $card->card_no,
                'change_type' => 'recharge',
                'amount' => 0,
                'before_balance' => 0,
                'after_balance' => 0,
                'before_available' => 0,
                'after_available' => 0,
                'before_frozen' => 0,
                'after_frozen' => 0,
                'operator_id' => $request->user->staff_id ?? 0,
                'operator_name' => $request->user->real_name ?? '系统',
                'remark' => '新建黑卡',
                'created_at' => date('Y-m-d H:i:s')
            ]);
            
            error_log("Successfully created card: " . json_encode($card));
            return $this->success($card, '创建成功');
        } catch (\Exception $e) {
            error_log("Error creating card: " . $e->getMessage());
            return $this->error('创建失败：' . $e->getMessage());
        }
    }

    /**
     * 生成卡号
     */
    private function generateCardNo(): string
    {
        $prefix = 'HK'; // 黑卡前缀
        $date = date('Ymd');
        
        // 增加随机性：使用6位随机数而不是4位
        $random = str_pad((string)mt_rand(1, 999999), 6, '0', STR_PAD_LEFT);
        
        // 添加毫秒级时间戳的最后3位来增加唯一性
        $milliseconds = substr(microtime(), 2, 3);
        
        $cardNo = $prefix . $date . $random . $milliseconds;
        
        // 如果卡号已存在，重新生成
        while (BlackCard::where('card_no', $cardNo)->exists()) {
            error_log("Card number collision detected: " . $cardNo);
            $random = str_pad((string)mt_rand(1, 999999), 6, '0', STR_PAD_LEFT);
            $milliseconds = substr(microtime(), 2, 3);
            $cardNo = $prefix . $date . $random . $milliseconds;
        }
        
        error_log("Generated new card number: " . $cardNo);
        return $cardNo;
    }

    /**
     * 获取黑卡详情
     */
    public function detail(Request $request): Response
    {
        $params = $request->get('params', []);
        $cardId = isset($params['id']) ? $params['id'] : null;
        
        if (!$cardId) {
            return $this->error('参数错误');
        }

        // 获取黑卡信息，同时加载关联数据
        $card = BlackCard::with(['user'])
            ->find($cardId);
            
        if (!$card) {
            return $this->error('黑卡不存在');
        }

        // 格式化状态和类型
        $card->status_text = $card->status ? '正常' : '禁用';
        $card->card_type_text = [
            'organization_prepaid' => '企业预付',
            'personal_member' => '个人会员'
        ][$card->card_type] ?? '未知';
        $card->card_level_text = [
            'black' => '黑卡',
            'platinum' => '白金卡'
        ][$card->card_level] ?? '未知';

        // 格式化金额
        $card->balance = number_format($card->balance, 2);
        $card->available_balance = number_format($card->available_balance, 2);
        $card->frozen_balance = number_format($card->frozen_balance, 2);
        $card->total_consumption = number_format($card->total_consumption, 2);
        $card->daily_limit = $card->daily_limit ? number_format($card->daily_limit, 2) : null;
        $card->monthly_limit = $card->monthly_limit ? number_format($card->monthly_limit, 2) : null;

        return $this->success($card);
    }

    /**
     * 更新黑卡信息
     */
    public function update(Request $request): Response
    {
        $params = $request->get('params', []);
        $cardId = isset($params['id']) ? $params['id'] : null;
        $data = $request->post();
        
        if (!$cardId) {
            return $this->error('参数错误');
        }

        // 获取黑卡
        $card = BlackCard::find($cardId);
        if (!$card) {
            return $this->error('黑卡不存在');
        }

        // 验证数据
        $validate = new BlackCardValidate();
        if (!$validate->scene('edit')->check($data)) {
            return $this->error($validate->getError());
        }

        try {
            // 更新黑卡信息
            $card->update($data);
            
            // 记录操作日志
            CardBalanceLog::create([
                'card_id' => $card->card_id,
                'card_no' => $card->card_no,
                'change_type' => 'update',
                'amount' => 0,
                'before_balance' => $card->balance,
                'after_balance' => $card->balance,
                'before_available' => $card->available_balance,
                'after_available' => $card->available_balance,
                'before_frozen' => $card->frozen_balance,
                'after_frozen' => $card->frozen_balance,
                'operator_id' => $request->user->staff_id ?? null,
                'operator_name' => $request->user->real_name ?? null,
                'remark' => '更新黑卡信息'
            ]);
            
            return $this->success($card, '更新成功');
        } catch (\Exception $e) {
            return $this->error('更新失败：' . $e->getMessage());
        }
    }

    /**
     * 修改黑卡状态
     */
    public function updateStatus(Request $request): Response
    {
        $params = $request->get('params', []);
        $cardId = isset($params['id']) ? $params['id'] : null;
        $status = $request->input('status');
        
        if (!$cardId || !in_array($status, [0, 1])) {
            return $this->error('参数错误');
        }

        try {
            $card = BlackCard::find($cardId);
            if (!$card) {
                return $this->error('黑卡不存在');
            }

            $oldStatus = $card->status;
            $card->update(['status' => $status]);
            
            // 记录操作日志
            CardBalanceLog::create([
                'card_id' => $card->card_id,
                'card_no' => $card->card_no,
                'change_type' => 'status',
                'amount' => 0,
                'before_balance' => $card->balance,
                'after_balance' => $card->balance,
                'before_available' => $card->available_balance,
                'after_available' => $card->available_balance,
                'before_frozen' => $card->frozen_balance,
                'after_frozen' => $card->frozen_balance,
                'operator_id' => $request->user->staff_id ?? null,
                'operator_name' => $request->user->real_name ?? null,
                'remark' => sprintf('修改状态：%s -> %s', $oldStatus ? '正常' : '禁用', $status ? '正常' : '禁用')
            ]);
            
            return $this->success(null, '状态更新成功');
        } catch (\Exception $e) {
            return $this->error('状态更新失败：' . $e->getMessage());
        }
    }
}
